<template>
  <!-- 创建广告计划表单 -->
  <el-form
    ref="campaignFormRef"
    :disabled="isReadOnly"
    :model="formData"
    :rules="rules"
    label-width="150px"
    class="campaign-form"
  >
    <!-- 使用配置进行渲染表单分组 -->
    <template v-for="(group, groupIndex) in formConfig" :key="groupIndex">
      <div class="form-group">
        <div class="form-group-title">{{ group.title }}</div>
        <div class="form-group-content">
          <!-- 遍历每个分组中的表单项 -->
          <template
            v-for="(field, fieldIndex) in group.fields"
            :key="fieldIndex"
          >
            <!-- 根据字段visible条件决定是否显示 -->
            <el-form-item
              v-if="getFieldVisibility(field)"
              :label="field.label"
              :prop="field.prop"
              :style="field.style"
            >
              <!-- 下拉选择框 -->
              <template v-if="field.type === 'select'">
                <el-tooltip
                  v-if="field.tooltip"
                  placement="top"
                  :content="getTooltipContent(field)"
                  :disabled="!getTooltipContent(field)"
                >
                  <el-select
                    v-model="formData[field.prop]"
                    :placeholder="field.placeholder"
                    :filterable="field.filterable"
                    :disabled="
                      isReadOnly ||
                      (field.disabled ? getFieldDisabled(field) : false)
                    "
                    :no-data-text="field.noDataText"
                  >
                    <el-option
                      v-for="option in getFieldOptions(field)"
                      :key="option.value"
                      :label="option.key"
                      :value="
                        option.value === 'string'
                          ? option.value
                          : Number(option.value)
                      "
                    >
                      <template v-if="field.prop === 'accountId'">
                        <div>{{ option.key }}</div>
                        <div class="text-gray-400 text-sm">
                          ID: {{ option.value }}
                        </div>
                      </template>
                    </el-option>
                  </el-select>
                </el-tooltip>
                <el-select
                  v-else
                  v-model="formData[field.prop]"
                  :placeholder="field.placeholder"
                  :filterable="field.filterable"
                  :disabled="
                    isReadOnly ||
                    (field.disabled ? getFieldDisabled(field) : false)
                  "
                  :no-data-text="field.noDataText"
                >
                  <el-option
                    v-for="option in getFieldOptions(field)"
                    :key="option.value"
                    :label="option.key"
                    :value="
                      option.value === 'string'
                        ? option.value
                        : Number(option.value)
                    "
                  >
                    <template v-if="field.prop === 'accountId'">
                      <div>{{ option.key }}</div>
                      <div class="text-gray-400 text-sm">
                        ID: {{ option.value }}
                      </div>
                    </template>
                  </el-option>
                </el-select>
              </template>

              <!-- 输入框 -->
              <template v-else-if="field.type === 'input'">
                <el-input
                  v-model="formData[field.prop]"
                  :placeholder="field.placeholder"
                  :maxlength="field.maxlength"
                  :show-word-limit="field.showWordLimit"
                  :disabled="isReadOnly"
                />
              </template>

              <!-- 数字输入框 -->
              <template v-else-if="field.type === 'number'">
                <el-input-number
                  v-model="formData[field.prop]"
                  :min="field.min"
                  :precision="field.precision"
                  :step="field.step"
                  :placeholder="field.placeholder"
                  :disabled="isReadOnly"
                />
              </template>

              <!-- 开关 -->
              <template v-else-if="field.type === 'switch'">
                <el-tooltip
                  v-if="field.tooltip"
                  placement="top"
                  :content="field.tooltip"
                >
                  <el-switch
                    v-model="formData[field.prop]"
                    :disabled="isReadOnly"
                  />
                </el-tooltip>
                <el-switch
                  v-else
                  v-model="formData[field.prop]"
                  :disabled="isReadOnly"
                />
              </template>

              <!-- 固定日期预算（周一到周日） -->
              <template v-else-if="field.type === 'budgetSchedule'">
                <div class="grid grid-cols-7 gap-2">
                  <div v-for="(_, index) in 7" :key="index" class="text-center">
                    <div class="mb-2">
                      {{
                        [
                          "周一",
                          "周二",
                          "周三",
                          "周四",
                          "周五",
                          "周六",
                          "周日"
                        ][index]
                      }}
                    </div>
                    <el-input-number
                      v-model="formData.budgetSchedule[index]"
                      :min="0"
                      :precision="2"
                      :step="0.01"
                      :placeholder="'不限'"
                      controls-position="right"
                      style="width: 100%"
                      :disabled="isReadOnly"
                    />
                  </div>
                </div>
              </template>
            </el-form-item>
          </template>
        </div>
      </div>
    </template>
  </el-form>
</template>

<script setup lang="ts">
import {
  ref,
  computed,
  watch,
  onMounted,
  defineEmits,
  defineProps,
  defineExpose
} from "vue";
import { getAdAccounts } from "@/api/promotion";
import { ElMessage } from "element-plus";
import { useCampaignSelect } from "../utils/hooks";

// 获取广告计划选项
const { campaignOptions: remoteOptions, loadCampaignOptions } =
  useCampaignSelect();

// 定义组件属性
const props = defineProps({
  // 表单数据
  modelValue: {
    type: Object,
    required: true
  },
  // 是否为只读模式
  isReadOnly: {
    type: Boolean,
    default: false
  },
  // 预设值，用于编辑或查看模式
  presetData: {
    type: Object,
    default: () => ({})
  }
});

// 定义事件
const emit = defineEmits(["update:modelValue", "submit", "validate"]);

// 表单引用
const campaignFormRef = ref();

// 广告账号列表
const adAccounts = ref<{ adAccountId: number; adAccountName: string }[]>([]);

// 本地表单数据
const formData = ref({
  accountId: "", // 投放账户
  adCategory: 1, // 广告分类，默认1:效果广告
  campaignType: 3, // 营销目标，默认3:转化
  marketingType: null, // 推广对象
  deliveryStrategy: null, // 出价策略
  cboAuthorized: false, // 计划预算优化
  budgetType: null, // 每日预算类型
  dayBudget: 0, // 每日固定预算
  budgetSchedule: [0, 0, 0, 0, 0, 0, 0], // 固定日期预算，对应周一到周日
  campaignName: "" // 计划名称
});

// 创建广告计划表单验证规则
const rules = {
  accountId: [{ required: true, message: "请选择广告账户", trigger: "change" }],
  marketingType: [
    { required: true, message: "请选择推广对象", trigger: "change" }
  ],
  deliveryStrategy: [
    { required: true, message: "请选择出价策略", trigger: "change" }
  ],
  campaignName: [
    { required: true, message: "请输入计划名称", trigger: "blur" },
    { max: 100, message: "超出可输入最长计划名称", trigger: "blur" }
  ]
};

// 加载广告账号列表
const loadAdAccounts = async () => {
  try {
    const data = await getAdAccounts();
    adAccounts.value = data || [];
  } catch (error) {
    console.error("获取广告账号列表失败:", error);
    ElMessage.error("获取广告账号列表失败");
  }
};

// 本地默认选项（仅在远程选项不可用时使用）
const defaultOptions = ref({
  // 广告分类
  adCategory: [{ key: "效果广告", value: 1 }],
  // 营销目标
  campaignType: [{ key: "转化", value: 3 }],
  // 推广对象
  marketingType: [
    { key: "应用推广", value: 1 },
    { key: "网站推广", value: 2 }
  ],
  // 出价策略
  deliveryStrategy: [
    { key: "目标成本", value: 2 },
    { key: "最低转化成本", value: 3 },
    { key: "目标成本上限", value: 4 }
  ],
  // 预算类型
  budgetType: [
    { key: "不限", value: 1 },
    { key: "每日固定预算", value: 2 },
    { key: "固定日期预算", value: 3 }
  ]
});

// 表单配置
const formConfig = computed(() => [
  // 投放账户分组
  {
    title: "投放账户",
    fields: [
      {
        type: "select",
        label: "投放账户",
        prop: "adAccountId",
        placeholder: "请选择广告账户",
        filterable: true,
        noDataText: "未找到匹配项",
        optionsSource: "adAccounts" // 特殊处理，使用adAccounts数据
      }
    ]
  },
  // 营销目标分组
  {
    title: "营销目标",
    fields: [
      {
        type: "input",
        label: "广告分类",
        prop: "adCategory",
        style: "display: none",
        optionsSource: "adCategory"
      },
      {
        type: "input",
        label: "营销目标",
        prop: "campaignType",
        style: "display: none",
        optionsSource: "campaignType"
      },
      {
        type: "select",
        label: "推广对象",
        prop: "marketingType",
        placeholder: "请选择推广对象",
        optionsSource: "marketingType"
      }
    ]
  },
  // 广告计划设置分组
  {
    title: "广告计划设置",
    fields: [
      {
        type: "select",
        label: "出价策略",
        prop: "deliveryStrategy",
        placeholder: "请选择出价策略",
        optionsSource: "deliveryStrategy",
        tooltip: true, // 使用tooltip
        getTooltipContent: value => {
          if (value === 4) {
            return "使用这个选项，Kwai的目标是控制每次转化的平均成本与所设置的出价在20%以内，同时在您预算范围内找到最多的转化量。您需要表达预算的基础上，表达成本的上限";
          } else if (value === 3) {
            return "使用lowest cost选项，我们的目标是在您预算范围能帮您取得最多的转化量，但可能不会严格控制达成的CPA，您取得的CPA可能会有波动";
          }
          return "";
        }
      },
      {
        type: "switch",
        label: "计划预算优化",
        prop: "cboAuthorized",
        visible: form => [3, 4].includes(form.deliveryStrategy),
        tooltip:
          "系统会不间断地在各广告组中自动寻找实现成效的最佳机会，并实时分配广告计划预算以获得最佳成效。Kwai建议一个计划下广告组在4到8个，以保证跑量能力的最大化。",
        optionsSource: "cboAuthorized"
      },
      {
        type: "select",
        label: "每日预算",
        prop: "budgetType",
        placeholder: "请选择预算类型",
        disabled: form => [3, 4].includes(form.deliveryStrategy),
        tooltip:
          "此预算是指计划为广告组花费的单日花费上限，其中单日指 UTC+0 时区下的每个自然日",
        optionsSource: "budgetType"
      },
      {
        type: "number",
        label: "每日固定预算(USD)",
        prop: "dayBudget",
        visible: form => form.budgetType === 2,
        min: 1,
        precision: 2,
        step: 0.01,
        placeholder: "请输入每日固定预算"
      },
      {
        type: "budgetSchedule",
        label: "固定日期预算(USD)",
        prop: "budgetSchedule",
        visible: form => form.budgetType === 3
      },
      {
        type: "input",
        label: "计划名称",
        prop: "campaignName",
        placeholder: "请输入计划名称",
        maxlength: 100,
        showWordLimit: true
      }
    ]
  }
]);

// 获取字段显示状态
const getFieldVisibility = field => {
  if (field.visible) {
    return field.visible(formData.value);
  }
  return true;
};

// 获取字段禁用状态
const getFieldDisabled = field => {
  if (typeof field.disabled === "function") {
    return field.disabled(formData.value);
  }
  return field.disabled;
};

// 获取字段选项
const getFieldOptions = field => {
  // 处理广告账号选项
  if (field.optionsSource === "adAccounts") {
    return adAccounts.value.map(item => ({
      key: item.adAccountName,
      value: item.adAccountId
    }));
  }

  // 优先使用远程获取的选项，如果不可用则使用默认选项
  const source = field.optionsSource;
  if (
    remoteOptions.value &&
    remoteOptions.value[source] &&
    remoteOptions.value[source].length > 0
  ) {
    return remoteOptions.value[source];
  }

  return defaultOptions.value[source] || [];
};

// 获取tooltip内容
const getTooltipContent = field => {
  if (field.getTooltipContent) {
    return field.getTooltipContent(formData.value[field.prop]);
  }

  if (field.prop === "deliveryStrategy") {
    if (formData.value.deliveryStrategy === 4) {
      return "使用这个选项，Kwai的目标是控制每次转化的平均成本与所设置的出价在20%以内，同时在您预算范围内找到最多的转化量。您需要表达预算的基础上，表达成本的上限";
    } else if (formData.value.deliveryStrategy === 3) {
      return "使用lowest cost选项，我们的目标是在您预算范围能帮您取得最多的转化量，但可能不会严格控制达成的CPA，您取得的CPA可能会有波动";
    }
  }

  return "";
};

// 格式化表单数据
const formatFormData = () => {
  const newFormData = { ...formData.value };

  // 根据预算类型处理数据
  if (newFormData.budgetType === 1) {
    // 预算类型为"不限"时，删除日预算和周预算
    delete newFormData.dayBudget;
    delete newFormData.budgetSchedule;
  } else if (newFormData.budgetType === 2) {
    // 预算类型为"每日固定预算"时，删除周预算
    delete newFormData.budgetSchedule;
  } else if (newFormData.budgetType === 3) {
    // 预算类型为"固定日期预算"时，删除日预算
    delete newFormData.dayBudget;
  }

  // 布尔值转换为数字
  if (typeof newFormData.cboAuthorized === "boolean") {
    newFormData.cboAuthorized = newFormData.cboAuthorized ? 1 : 0;
  }

  return newFormData;
};

// 表单验证
const validate = () => {
  return new Promise((resolve, reject) => {
    campaignFormRef.value.validate((valid, fields) => {
      if (valid) {
        const formattedData = formatFormData();
        resolve(formattedData);
      } else {
        reject(fields);
      }
    });
  });
};

// 重置表单
const resetForm = () => {
  campaignFormRef.value.resetFields();
};

// 监听出价策略变化
watch(
  () => formData.value.deliveryStrategy,
  newVal => {
    // 当出价策略为最低转化成本(3)或目标成本上限(4)时，预算类型限定为不限(1)
    if (newVal === 3 || newVal === 4) {
      formData.value.budgetType = 1;
    }
  }
);

// 监听props.modelValue变化，同步到本地formData
watch(
  () => props.modelValue,
  newVal => {
    console.log("modelValue newVal = ", newVal);
    // 深拷贝以避免直接修改props
    Object.assign(formData.value, newVal);
  },
  { deep: true, immediate: true }
);

// 监听本地formData变化，同步到父组件
watch(
  formData,
  newVal => {
    emit("update:modelValue", newVal);
  },
  { deep: true }
);

// 如果有预设数据，则使用预设数据
watch(
  () => props.presetData,
  newVal => {
    console.log("presetData newVal = ", newVal);
    if (newVal && Object.keys(newVal).length > 0) {
      Object.assign(formData.value, newVal);
    }
  },
  { immediate: true, deep: true }
);

// 对外暴露方法
defineExpose({
  validate,
  resetForm,
  formData,
  formatFormData
});

onMounted(() => {
  const fn = async () => {
    await loadAdAccounts();
    await loadCampaignOptions();
  };
  fn();
});
</script>

<style lang="scss" scoped>
.campaign-form {
  width: 100%;
}

.form-group {
  margin-bottom: 28px;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  overflow: hidden;
}

.form-group-title {
  padding: 12px 16px;
  font-weight: 600;
  font-size: 16px;
  background-color: #f6f9fe;
  border-bottom: 1px solid #e5e7eb;
}

.form-group-content {
  padding: 16px;
}
</style>

<style scoped>
.campaign-form :deep(.el-form-item__label) {
  white-space: nowrap;
}
</style>
